const net = require('net');
const { exec } = require('child_process');
const util = require('util');
const execAsync = util.promisify(exec);

class IPChecker {
    static isPrivateIP(ip) {
        const ipObj = net.isIP(ip);
        if (!ipObj) return true;  // 无效IP视为私有
        
        // IPv4 私有地址范围
        if (ipObj === 4) {
            const parts = ip.split('.').map(Number);
            return (
                parts[0] === 10 || // 10.0.0.0/8
                (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) || // 172.16.0.0/12
                (parts[0] === 192 && parts[1] === 168) || // 192.168.0.0/16
                parts[0] === 127 || // 127.0.0.0/8
                parts[0] === 169 && parts[1] === 254 // 169.254.0.0/16 链路本地地址
            );
        }
        
        // IPv6 私有地址
        if (ipObj === 6) {
            return (
                ip.toLowerCase().startsWith('fc00:') || // Unique Local Address (fc00::/7)
                ip.toLowerCase().startsWith('fd') || // Unique Local Address (fd00::/8)
                ip.toLowerCase().startsWith('fe80:') || // Link Local Address (fe80::/10)
                ip === '::1' || // Loopback
                ip.toLowerCase().startsWith('2001:0db8:') || // Documentation prefix (2001:db8::/32)
                ip.toLowerCase().startsWith('ff') || // Multicast (ff00::/8)
                ip.toLowerCase().startsWith('100:') || // Reserved by IETF (0100::/64)
                ip.toLowerCase().startsWith('64:ff9b:') // IPv4-IPv6 translation (64:ff9b::/96)
            );
        }
        
        return false;
    }

    static async ping(ip) {
        try {
            const platform = process.platform;
            const pingCmd = platform === 'win32' ? 
                `ping -n 1 -w 2000 ${ip}` : 
                `ping -c 1 -W 2 ${ip}`;
            
            await execAsync(pingCmd);
            return true;
        } catch {
            return false;
        }
    }

    static async filterPublicIPs(ipv4s, ipv6s) {
        const publicIPv4s = [];
        const publicIPv6s = [];

        // 过滤并检查 IPv4
        for (const ip of ipv4s) {
            if (!this.isPrivateIP(ip) && await this.ping(ip)) {
                publicIPv4s.push(ip);
            }
        }

        // 过滤并检查 IPv6
        for (const ip of ipv6s) {
            if (!this.isPrivateIP(ip) && await this.ping(ip)) {
                publicIPv6s.push(ip);
            }
        }

        return [publicIPv4s, publicIPv6s];
    }
}

module.exports = { IPChecker }; 